#include <dict.h>
#include <attrib.h>
#include "CuTest.h"
#include <stdio.h>

void TestDictNew(CuTest *tc) {
	dict_p dict = dict_new();
	CuAssertPtrNotNull(tc, dict);
}

void TestDictAddAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	attrib_p attrib;
	int i;

	for (i=0; i<size; i++) {
		attrib = attrib_new(k[i], v);
		CuAssertPtrNotNull(tc, dict_add(dict, attrib));
		if (!i) {
			CuAssertTrue(tc, list_at_first((list_p)dict));
			CuAssertTrue(tc, list_at_end((list_p)dict));
		}
		CuAssertIntEquals(tc, i+1, list_size((list_p)dict));
	}
	CuAssertIntEquals(tc, size, list_size((list_p)dict));
}

void TestDictAddNewAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	int i;

	for (i=0; i<size; i++) {
		CuAssertPtrNotNull(tc, dict_add_new(dict, k[i], v));
		CuAssertIntEquals(tc, i+1, list_size((list_p)dict));
	}
	CuAssertIntEquals(tc, size, list_size((list_p)dict));
}

void TestDictGetAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	attrib_p attrib;
	int i;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v);


	attrib = dict_get(dict); i=0;
	while (attrib) {
		i++;
		list_advance((list_p)dict);
		attrib = dict_get(dict);
	}
	CuAssertIntEquals(tc, size, i);
	CuAssertTrue(tc, list_cur_is_empty((list_p)dict));
	CuAssertFalse(tc, dict_get(dict));
}

void TestDictIsEmpty(CuTest *tc) {
	dict_p dict = dict_new();

	CuAssertTrue(tc, dict_is_empty(dict));

	dict_add_new(dict, "foo", "bar");

	CuAssertFalse(tc, dict_is_empty(dict));
}

void TestDictToFirstAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	int i;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v);

	while (!list_at_end((list_p)dict))
		list_advance((list_p)dict);

	dict_to_first(dict);

	CuAssertTrue(tc, list_at_first((list_p)dict));
}

void TestDictNextAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	int i;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v);

	for (i=1; dict_next(dict); i++);

	CuAssertIntEquals(tc, size, i);
	CuAssertTrue(tc, list_cur_is_empty((list_p)dict));
}

void TestDictAtLastAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	int i;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v);

	
	for (i=1; i<size; i++)
		dict_next(dict);

	CuAssertTrue(tc, dict_at_last(dict));
}

void TestDictAttribFindNextKey(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v = "foo";
	attrib_p attrib;
	int i;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v);

	attrib = dict_find_next_key(dict, "4");
	CuAssertStrEquals(tc, "4", attrib_get_key(attrib));

	attrib = dict_find_next_key(dict, "3");
	CuAssertStrEquals(tc, "3", attrib_get_key(attrib));

	attrib = dict_find_next_key(dict, "4");
	CuAssertFalse(tc, attrib);
}

void TestDictAttribFindValueAll(CuTest *tc) {
	dict_p dict = dict_new();
	const int size = 5;
	char *k[] = {"0","1","2","3","4"};
	char *v[] = {"0","1","0","1","0"};
	int i;
	list_p list;

	for (i=0; i<size; i++) 
		dict_add_new(dict, k[i], v[i]);

	list = dict_find_all_values(dict, "1");
	CuAssertIntEquals(tc, 2, list_size(list));

	list = dict_find_all_values(dict, "0");
	CuAssertIntEquals(tc, 3, list_size(list));
}

void TestDictSetAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	attrib_p attrib;

	dict_add_new(dict, "foo", "bar");
	dict_set_key(dict, "foo", "BAR");

	CuAssertIntEquals(tc, 1, list_size((list_p)dict));

	attrib = dict_get(dict);

	CuAssertStrEquals(tc, "BAR", attrib_get_value(attrib));
}

void TestDictSetAttrib_NewAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	attrib_p attrib;
	attrib_p tmp = attrib_new("foo","bar");

	attrib = dict_set_key(dict, "foo", "bar");

	CuAssertPtrNotNull(tc, attrib);
	CuAssertIntEquals(tc, 0, attrib_cmp(attrib, tmp));
}

void TestDictRemoveAttrib(CuTest *tc) {
	dict_p dict = dict_new();
	int size = 10;
	int i;

	for (i=0; i<size; i++)
		dict_add_new(dict, "foo", "bar");

	dict_remove(dict);

	CuAssertIntEquals(tc, size-1, list_size((list_p)dict));
}

